/**
  ******************************************************************************
  * File Name          : thapp.c
  * Description        : This file provides code for the configuration
  *                      of the lora e22-400t22s instances.
  ******************************************************************************
  * @attention
  *
  ******************************************************************************
  */
#include "tskcfg.h"
#include "bsp.h"
#include "sensor.h"
#include "si2c_sht3x2x.h"
#include "edct.h"

/* T&H Sensor task */
TaskHandle_t xSensor_Thd = NULL;
StaticTask_t xSensor_Tcb;
StackType_t  xSensor_Stk[ SENSOR_STACK_SIZE ];
void vSensor_Task( void * pvParameters );

typedef struct
{
	volatile float temperature;
	volatile float humidity;
}Sht30_DataType;

typedef struct
{
	volatile uint16_t CO2;
	volatile uint16_t TVOC;
}SGP30_DataType;

static uint8_t sht30_check_rational(float temperature, float humidity)
{
	if((temperature < -40.0) || (temperature > 120.0))
	{
		return 1;
	}
	
	if((humidity < 0.0) || (humidity > 120.0))
	{
		return 2;
	}

	return 0;
}

static uint8_t sgp30_check_rational(uint16_t CO2, uint16_t TVOC)
{
	if(CO2 > 60000)
	{
		return 1;
	}
	
	if(TVOC > 60000)
	{
		return 2;
	}

	return 0;
}

static void measure(void)
{
	uint8_t err;
	static uint8_t fail_sht30 = 0;
  static uint8_t fail_sgp30 = 0;
	uint8_t active_sht30 = 0;
  uint8_t active_sgp30 = 0;
	volatile Sht30_DataType sht30_data;
	volatile SGP30_DataType sgp30_data;
  
	err = SHT30_GetSingleMeasure(&sht30_data.temperature, &sht30_data.humidity);
	if(err == 0)
	{
		active_sht30 = 1;
    fail_sht30 = 0;
	}
	else
	{
		active_sht30 = 0;
		fail_sht30++;
		printf("sht30 err:%d\r\n", err);
	}
	
	if((active_sht30 != 0) && (sht30_check_rational(sht30_data.temperature, sht30_data.humidity) == 0))
	{
		SENSOR.Status_T = 1;
		SENSOR.Status_H = 1;
		SENSOR.temperature = sht30_data.temperature;
		SENSOR.humidity = sht30_data.humidity;
    
    LED3_Toggle();
	}
	else
	{
		SENSOR.Status_T = 0.0;
		SENSOR.Status_H = 0.0;
    LED3(1);
	}
	
  vTaskDelay(75);
  
	if(Edct_RunPara.tvoc_en == 1)
	{
		err = SGP30_GetSingleMeasure(&sgp30_data.CO2, &sgp30_data.TVOC);
		if(err == 0)
		{
			active_sgp30 = 1;
			fail_sgp30 = 0;
		}
		else
		{
			active_sgp30 = 0;
			fail_sgp30++;
			printf("sgp30 err:%d\r\n", err);
		}
		
		if((active_sgp30 != 0) && (sgp30_check_rational(sgp30_data.CO2, sgp30_data.TVOC) == 0))
		{
			SENSOR.Status_CO2  = 1;
			SENSOR.Status_TVOC = 1;
			SENSOR.co2         = sgp30_data.CO2;
			SENSOR.tvoc        = sgp30_data.TVOC;
		}
		else
		{
			SENSOR.co2  = 0;
			SENSOR.tvoc = 0;
		}
	}
	else
	{
		SENSOR.Status_CO2  = 0;
		SENSOR.Status_TVOC = 0;
		SENSOR.co2         = 0;
		SENSOR.tvoc        = 0;
		fail_sgp30         = 0;
		active_sgp30       = 0;
		vTaskDelay(350);
	}
  
	if((fail_sht30 > 9) || (fail_sgp30 > 9))
	{
		SENSOR.Status_T = 0;
		SENSOR.Status_H = 0;
		SENSOR.temperature = 0.0;
		SENSOR.humidity = 0.0;
    
    SENSOR.Status_CO2  = 0;
		SENSOR.Status_TVOC = 0;
		SENSOR.co2         = 0;
		SENSOR.tvoc        = 0;
    
		sI2C_PowerDown();
		vTaskDelay(1000);
		sI2C_PowerUp();
    vTaskDelay(1000);
    
    SGP30_ReInit();
    
		fail_sht30 = 0;
    fail_sgp30 = 0;
    
		printf("si2c reset power!\r\n");
	}
	
	vTaskDelay(75);
}

void vSensor_Task( void * pvParameters )
{
	sI2C_Init();
	sI2C_SgpInit();
  
	if(Edct_RunPara.tvoc_en == 1)
	{
    SGP30_ReInit();
	}

	while(1)
	{
		measure();
    printf("t:%.01f, h:%.01f\r\n", SENSOR.temperature, SENSOR.humidity);
    printf("v:%d, c:%d\r\n", SENSOR.tvoc, SENSOR.co2);
	}
}
